package com.msc.mc.filter;

import java.awt.Color;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.lowagie.text.Element;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfGState;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfStamper;
import com.msc.sdm.application.Core;
import com.msc.sdm.config.ObjectTypeConfig;
import com.msc.sdm.config.ObjectTypeExpression;
import com.msc.sdm.config.ResultType;
import com.msc.sdm.config.ResultValue;
import com.msc.sdm.db.FileHandle;
import com.msc.sdm.tool.ele.ELEvaluator;
import com.msc.sdm.util.EventHandlingUtil;
import com.msc.sdm.util.SDMUtil;
import com.msc.sdm.vo.DbObject;

public class FileDowloadFilter implements Filter {
	@Override
	public void destroy() {

	}

	public String getContentType(DbObject localDbObject, ObjectTypeConfig localObjectTypeConfig, String expr)
			throws Exception {

		ObjectTypeExpression exprType = localObjectTypeConfig.compileExpression(expr);
		ResultValue exprResult = exprType.evaluateOnObject(localDbObject);
		ResultType exprResultType = exprResult.getValueType();

		int i = (exprResultType.isFile()) || (exprResultType.isList()) ? 1 : 0;
		if (i == 0) {
			throw new ServletException("Expression '" + expr + "' doesn't point to a file.");
		}
		FileHandle handle = null;
		if (exprResultType.isList()) {
			ResultValue localObject7 = (ResultValue) exprResult.getList().get(0);
			handle = localObject7.getFile();
		} else {
			handle = exprResult.getFile();
		}
		String extension = handle.getExtension();
		String contentType = Core.getConfig().getMimeTypeFromExtension(extension);
		contentType = contentType.trim();

		return contentType;

	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
			throws IOException, ServletException {
		HttpServletRequest paramHttpServletRequest = (HttpServletRequest) request;
		String userName = (String) paramHttpServletRequest.getSession().getAttribute("username");

		// get object id
		String oid = paramHttpServletRequest.getParameter("oid");
		if (oid == null || "".equals(oid)) {
			filterChain.doFilter(request, response);
		} else {
			// get Object type Object
			DbObject localDbObject = new DbObject(oid);

			ObjectTypeConfig localObjectTypeConfig = Core.getConfig()
					.getObjectTypeById(localDbObject.getObjectTypeId());
			String expr = paramHttpServletRequest.getParameter("expr");
			ELEvaluator.setUserSession(paramHttpServletRequest);
			ObjectTypeExpression exprType = localObjectTypeConfig.compileExpression(expr);

			// resultValue.getString();
			try {
				// ObjectTypeExpression projectExpr =
				// localObjectTypeConfig.compileExpression("project.name");
				// ResultValue projectValue = projectExpr.evaluateOnObject(localDbObject);

				// SimMgrDbObjectList userGroupList = Tools.getConnection().search("UserGroup",
				// "[ users.name == '" + userName
				// + "' ].ProjectSubjects:ProjectSubject[role.name != 'Project-Visitor' AND
				// projectDomain.projectName == '"
				// + projectValue + "']");

				// if (userGroupList != null && userGroupList.size() > 0) {
				HttpServletResponse resp = (HttpServletResponse) response;
				try {
					String contentType = null;
					try {
						contentType = getContentType(localDbObject, localObjectTypeConfig, expr);
					} catch (NullPointerException ex) {

					}
					if ("application/pdf".equals(contentType)) {
						
						ResultValue exprResult = exprType.evaluateOnObject(localDbObject);
						ResultType exprResultType = exprResult.getValueType();

						int i = (exprResultType.isFile()) || (exprResultType.isList()) ? 1 : 0;
						if (i == 0) {
							throw new ServletException("Expression '" + expr + "' doesn't point to a file.");
						}
						FileHandle handle = null;
						if (exprResultType.isList()) {
							ResultValue localObject7 = (ResultValue) exprResult.getList().get(0);
							handle = localObject7.getFile();
						} else {
							handle = exprResult.getFile();
						}
						String fileName = handle.getName();

						String encodeFileName = URLEncoder.encode(fileName, "UTF-8").replace("+", "%20");

						resp.setContentType(contentType + ";charset=UTF-8");
						String userAgent = paramHttpServletRequest.getHeader("User-Agent");
						Object localObject1 = paramHttpServletRequest.getParameter("isAttachment");
						boolean bool2 = localObject1 == null ? true
								: Boolean.valueOf((String) localObject1).booleanValue();
						String str9 = retrieveContentDispositionHeaderValue(fileName, encodeFileName, bool2, userAgent);
						resp.setHeader("Content-Disposition", str9);
						ByteArrayOutputStream out = new ByteArrayOutputStream();
						BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
						handle.exportFile(out);
						InputStream input = new ByteArrayInputStream(out.toByteArray());
						
						//------------------------------------------------------//
						String markStr = userName ;
						String typeName = localObjectTypeConfig.getName();
						//System.out.println( "----typeName : " + typeName );
						if( "NIOMatSpecification".equals( typeName ) ) {
							ObjectTypeExpression exprStatus = localObjectTypeConfig.compileExpression( "status" );
							ResultValue statusResult = exprStatus.evaluateOnObject(localDbObject);
							if( !statusResult.isNull() ) {
								String status = statusResult.getString() ;
								//System.out.println( "----Status : " + status );
								if( "DeActive".equals( status ) ) {
									markStr =  "DeActive  " + userName ;
								}
							}
						}
						//------------------------------------------------------//
						
						ByteArrayOutputStream extout = waterMark(input, markStr );

						bos.write(extout.toByteArray());

						bos.close();
						out.close();
						out.flush();

						EventHandlingUtil.fireFileDownloadCompletedEvent(
								SDMUtil.getFormattedJSONDescription("msg.fileDownload.objectType",
										new String[] { handle.getName(), localObjectTypeConfig.getName() }));

						// fireFileDownloadCompletedEvent(SDMUtil.getFormattedJSONDescription("msg.fileDownload.objectType",
						// new String[] { handle.getName(), localObjectTypeConfig.getName()
						// }),userName);

					} else {
						filterChain.doFilter(request, response);
					}
				} catch (Exception ex) {
					ex.printStackTrace();

				}
				// } else {
				// ((HttpServletResponse) response).setContentType("text/html; charset=UTF-8");
				// ((HttpServletResponse) response).getWriter().write(
				// "<html><script language='javascript' type='text/javascript'> alert('Hello
				// World!');</script> </html>");
				// ((HttpServletResponse) response).sendRedirect(
				// ((HttpServletRequest) request).getContextPath() +
				// "/facelets/main/application.xhtml");
				//
				// }

			} catch (Exception ex) {
				ex.printStackTrace();
			}
		}
	}

//	public static ByteArrayOutputStream waterMark(InputStream input, String waterMarkName) {
//		ByteArrayOutputStream out = new ByteArrayOutputStream();
//		try {
//			PdfReader reader = new PdfReader(input);
//
//			PdfStamper stamper = new PdfStamper(reader, out);
//
//			// stamper.setEncryption("43210".getBytes(), "1234".getBytes(), 3, false);
//			BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); 
//			int total = reader.getNumberOfPages() + 1;
//
//			PdfContentByte under;
//			com.lowagie.text.Rectangle pageRect = null;
//			for (int i = 1; i < total; i++) {
//				pageRect = stamper.getReader().getPageSizeWithRotation(i);
//				float x = pageRect.getWidth() / 3;
//				float y = pageRect.getHeight() / 3 - 10;
//				under = stamper.getOverContent(i);
//				// under = stamper.getUnderContent(i);
//
//				under.saveState();
//				// set Transparency
//				PdfGState gs = new PdfGState();
//				gs.setFillOpacity(0);
//				under.setGState(gs);
//				under.restoreState();
//				under.beginText();
//				under.setFontAndSize(base, 60);
//				under.setColorFill(new Color(19, 212, 200));
//
//				under.showTextAligned(Element.ALIGN_CENTER, waterMarkName, x, y, 55);
//				under.endText();
//				under.setLineWidth(1f);
//				under.stroke();
//			}
//			stamper.close();
//
//		} catch (Exception e) {
//			e.printStackTrace();
//
//		}
//		return out;
//	}
	
	public static ByteArrayOutputStream waterMark(InputStream input, String waterMarkName) {
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		try {
			PdfReader reader = new PdfReader(input);

			PdfStamper stamper = new PdfStamper(reader, out); 
			BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
			 
			int total = reader.getNumberOfPages() + 1;

			PdfContentByte under;

			Rectangle pageRect = null;
			for (int i = 1; i < total; i++) {
				pageRect = stamper.getReader().getPageSizeWithRotation(i);
				float x = 0;
				float y = 0;
				for (int r = 1; r < pageRect.getWidth()/100; r++) {
					for (int j = 1; j < pageRect.getHeight() /36; j++) {
						x =  r * 100;
						y =  j * 36;
						under = stamper.getOverContent(i);
						// under = stamper.getUnderContent(i);

						under.saveState();
						PdfGState gs = new PdfGState();
						gs.setFillOpacity(0);
						under.setGState(gs);
						under.restoreState();
						under.beginText();
						under.setFontAndSize(base, 8);
						under.setColorFill(new Color(204, 204, 204));
						under.showTextAligned(Element.ALIGN_CENTER, waterMarkName, x, y, 25);//  25 这个是斜率
						under.endText();
						under.setLineWidth(1f);
						under.stroke();
					}
				}

			}
			stamper.close();

		} catch (Exception e) {
			e.printStackTrace();

		}
		return out;
	}

	private String retrieveContentDispositionHeaderValue(String fileName, String encodeFileName, boolean paramBoolean,
			String userAgent) {
		String name = fileName.replaceAll("[,:\"]", "_");

		String title = "filename=\"" + name + "\"; filename*=UTF-8''" + encodeFileName;
		if (userAgent.contains("MSIE 7.0")) {
			title = "filename=\"" + encodeFileName + "\"";
		}
		if (paramBoolean) {
			title = "attachment; " + title + "; filename*=UTF-8''" + encodeFileName;
		}
		return title;
	}

	@Override
	public void init(FilterConfig config) throws ServletException {

	}

}
